﻿using System;
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
using Missbot.AIModule.Base;
using Missbot.Common;
using Missbot.Core.Base;
using Missbot.Core.Cache;
using Missbot.Core.SyntaxChecker.ParamCheckers;

namespace Missbot.AIModule.Record
{
    [UsedImplicitly]
    public class HelloMod : IAIModule, IDataMgr
    {
        public override string Name => "打招呼";
        public override AIPriority Priority => AIPriority.High;

        private List<HelloRecord> HelloList = new();

        public void RefreshData()
        {
            HelloList = HelloRecordDA.GetAll();
        }

        protected override bool OnInboxImpl(InboxSession session)
        {
            if (base.OnInboxImpl(session))
            {
                return true;
            }

            if (session.Group == null)
            {
                return false;
            }

            ProcessHello(session);
            return false;
        }

        private void ProcessHello(InboxSession session)
        {
            var hello = HelloList.FirstOrDefault(h => h.GroupID == session.Group.ID && h.UserID == session.User.ID);
            if (hello == null)
            {
                return;
            }

            var id = Guid.NewGuid().ToString();
            var key = $"Hello-{session.Group.ID}-{session.User.ID}";
            var helloCache = RapidCacher.GetCache
                (key, CommonUtil.UntilTommorow(),
                 () => new HelloCache
                 {
                     ID = id,
                     GroupID = session.Group.ID,
                     LastUpdateTime = DateTime.Now,
                     UserID = session.User.ID
                 });

            if (helloCache.ID != id)
            {
                return;
            }

            session.SendBack(hello.Content);
        }

        [ModuleEnter(Command = "打招呼设定", Description = "设定每天打招呼的内容", SyntaxHint = "[打招呼内容]", ChannelType = ChannelType.Messaging)]
        public bool SaveHelloContent(InboxSession session, UnlimitedStr contentParam)
        {
            var content = contentParam.Data;
            var query = HelloList.FirstOrDefault(h => h.GroupID == session.Group.ID && h.UserID == session.User.ID);
            if (query == null)
            {
                var hello = new HelloRecord
                {
                    Id = Guid.NewGuid().ToString(),
                    GroupID = session.Group.ID,
                    UserID = session.User.ID,
                    Content = content
                };
                hello.Insert();

                HelloList.Add(hello);
            }
            else
            {
                query.Content = content;
                query.Update();
            }

            session.SendBack("招呼内容设定成功");
            return true;
        }

        [ModuleEnter(Command = "打招呼", Description = "发送打招呼的内容", ChannelType = ChannelType.Messaging)]
        public bool SayHello(InboxSession session)
        {
            var query = HelloList.FirstOrDefault(h => h.GroupID == session.Group.ID && h.UserID == session.User.ID);
            if (query == null)
            {
                session.SendBack("你还没有设定过招呼内容哦~(请使用【打招呼设定】命令来设定每日打招呼内容！)");
                return false;
            }

            session.SendBack(query.Content);
            return true;
        }

        [ModuleEnter(Command = "打招呼删除", Description = "删除打招呼的内容", ChannelType = ChannelType.Messaging)]
        public bool DeleteHello(InboxSession session)
        {
            var query = HelloList.FirstOrDefault(h => h.GroupID == session.Group.ID && h.UserID == session.User.ID);
            if (query == null)
            {
                session.SendBack("你还没有设定过招呼内容哦~");
                return false;
            }

            query.Remove();
            HelloList.Remove(query);

            session.SendBack("删除成功！");
            return true;
        }
    }

    public class HelloCache
    {
        public string ID { get; init; }
        public string GroupID { get; set; }
        public string UserID { get; set; }
        public DateTime LastUpdateTime { get; set; }
    }
}